<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of socket_server
 *
 * @author Administrator
 */
class socket_server {
    protected $ip; //服务器ip
    protected $post; // 服务器端口
    protected $close_instruction; //关闭服务器指令
    protected $sock;//创建的socket对象
    protected $error;//保存错误信息
    //put your code here
    public function __construct($ip = '127.0.0.1',$port=1234,$close_instruction = 'close::socket::server')
    {
        $this->CI =& get_instance();
        $this->ip = $this->set_ip($ip);
        $this->port = $this->set_port($port);
        $this->close_instruction = $close_instruction;
        $this->error = '';
    }
    /*
     * 创建一个server
     */
    public function init()
    {
        if(!$this->ip){throw new Exception('ip 错误 ');return false;}
        if(!$this->port){throw new Exception('端口 错误 ');return false;}
        //创建一个SOCKET
        if (($this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false)
	{
                throw new Exception("socket_create() 失败的原因是:" . socket_strerror(socket_last_error()) . "\n");
		return false;
	}
	//阻塞模式
	if (socket_set_block($this->sock) == false)
	{
		throw new Exception("socket_set_block() 失败的原因是:" . socket_strerror(socket_last_error()) . "\n");
		return false;
	}
	//绑定到socket端口
	if (socket_bind($this->sock, $this->ip, $this->port) == false)
	{
		throw new Exception("socket_bind() 失败的原因是:" . socket_strerror(socket_last_error()) . "\n");
		return false;
	}
	//开始监听
	if (socket_listen($this->sock, 4) == false)
	{
		throw new Exception("socket_listen() 失败的原因是:" . socket_strerror(socket_last_error()) . "\n");
		return false;
	}
        return true;
    }
    /*
     * 读取远程服务器发送的信息
     * return 
     * ******************************************************
     * bool false 如果返回 flase 则代表了出错 或者是关闭
     * bool true 未收到消息 
     * string 收到的消息
     * ******************************************************
     */
    public function send()
    {
        if (($msgsock = socket_accept($this->sock)) === false)
        {
            throw new Exception("socket_accept() failed: reason: " . socket_strerror(socket_last_error()) . "\n");
            return false;
        }

        //收到的信息
        $buf = socket_read($msgsock, 8192);
        //发到客户端
        $msg = "welcome \n";
        if (socket_write($msgsock, $buf, strlen($buf)) === false)
        {
            throw new Exception("socket_write() failed: reason: " . socket_strerror(socket_last_error()) ."\n");
            return false;
        }
        //如果接收的是 关闭指令 那么就关闭socket
        if($buf == $this->close_instruction)
        {
            socket_close($this->sock);
            $this->error .= "socket关闭成功" ;
            return false;
        }
        socket_close($msgsock);
        return $buf;
    }
    
    /*****************************************************
     * 如果需要规定发送到客户端的返回值  那么只能一步一步来咯
     *****************************************************
     */
    //查询是否有链接
    public function accept()
    {
        if (($this->msgsock = socket_accept($this->sock)) === false)
        {
            throw new Exception("socket_accept() failed: reason: " . socket_strerror(socket_last_error()) . "\n");
            return false;
        }
    }
    
    /**
     * 接收消息
     */
    public function read()
    {
        //收到的信息
        return $this->buf = socket_read($this->msgsock, 8192);
    }
    /*
     * 发送的信息
     */
    public function write($msg)
    {
        $msg = urlencode($msg);
        if (socket_write($this->msgsock, $msg, mb_strlen($msg)) === false)
        {
            throw new Exception("socket_write() failed: reason: " . socket_strerror(socket_last_error()) ."\n");
            return false;
        }
    }
    /*
     * 关闭连接
     */
    public function close()
    {
        //如果接收的是 关闭指令 那么就关闭socket
        if($this->buf == $this->close_instruction)
        {
            socket_close($this->sock);
            $this->error .= "socket关闭成功" ;
            return false;
        }
        socket_close($this->msgsock);
        return true;
    }
    
    /*
     * 返回错误信息
     */
    public function get_error()
    {
        return $this->error;
    }
    /*
     * 设置ip 如果需要更换服务器ip的话
     */
    public function set_ip($ip)
    {
        if(Verification::ip($ip))
        {
            $this->ip = $ip;
        }
        else
        {
            $this->ip = false;
        }
    }
    /*
     * 设置端口 如果需要更换服务器ip的话
     */
    public function set_port($port)
    {
        if(Verification::port($port))
        {
            $this->port = $port;
        }
        else
        {
            $this->port = false;
        }
    }
}